package de.rj.urwalking.util;


import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.zip.GZIPOutputStream;

//import java.io.BufferedOutputStream;

import android.util.Log;

import de.rj.urwalking.config.Config;


/**
 * @author Richard Schaller
 * @author adapted by mka
 */
public class FileUploadUtil {

	private static final String TAG = Config.UPLOADTAG;
	
	FileInputStream fileInputStream = null;
	
	private static final String boundary = "***40ad906d561e76aed8faa081faec2cbc***";
	private static final String lineEnding = "\r\n";
	
	private static final String algo = "MD5";
	
	private static final int BUFFERSIZE = 1024;

	public static String uploadFile(String server, String filepath) throws IOException {
		String rsp = null;
		String strHash = null;
		HttpURLConnection connection = null;
		FileInputStream fileInputStream = null;
		try {
			
			Log.i(TAG, FileUploadUtil.class.getName()
					+ " Try to prepare file "+filepath+" for upload.");
			fileInputStream = new FileInputStream(filepath);
			
			//DEBUG
			//strHash = md5HashTextFile(new File(filepath));
			strHash="testhash";
			
			URL connectURL = new URL("http://" + server);
			
			//get new http connection -> cast according to http://developer.android.com/reference/java/net/HttpURLConnection.html
			connection = (HttpURLConnection) connectURL.openConnection();
			
			//setup before connection becomes alive
			connection.setDoInput(true); 
			connection.setDoOutput(true); //must be true because the request contains a body
			connection.setUseCaches(false);
			connection.setRequestProperty("ACCEPT_CHARSET", "utf-8");
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Connection", "Keep-Alive");
			connection.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);
			connection.setRequestProperty("Accept", "xml");
			connection.addRequestProperty("Accept", "csv");
			connection.addRequestProperty("Accept", "gz");
			
			DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
			
			dataOutputStream.writeBytes("--" + boundary + lineEnding);
			dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"hash\"" + lineEnding);
			dataOutputStream.writeBytes(lineEnding);
			dataOutputStream.writeBytes(strHash + lineEnding);
			dataOutputStream.writeBytes("--" + boundary + lineEnding);			
			dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"uploaded_file_zipped\";filename=\""+ filepath + "\"" + lineEnding);
			dataOutputStream.writeBytes(lineEnding);
			
			//DEBUG:
			GZIPOutputStream gzipOutputStream = new GZIPOutputStream(dataOutputStream);
			//BufferedOutputStream bous = new BufferedOutputStream(dataOutputStream);
			
			// write file
			byte[] buffer = new byte[BUFFERSIZE];
			while(true) {
				int readBytes = fileInputStream.read(buffer);
				if(readBytes < 0) {
					break;
				}
				
				gzipOutputStream.write(buffer, 0, readBytes);
				//bous.write(buffer,0,readBytes);
			}
			
			gzipOutputStream.finish();
			//bous.flush();
			
			dataOutputStream.writeBytes(lineEnding);
			dataOutputStream.writeBytes("--" + boundary + "--" + lineEnding);
			dataOutputStream.flush();

			
			BufferedReader bufferedReader  = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	        StringBuilder stringBuilder = new StringBuilder();
	        String line;
	        while((line = bufferedReader.readLine()) != null) {
	        	stringBuilder.append(line + '\n');
	        }
	        
	        rsp = stringBuilder.toString();
	        Log.i(TAG, "Upload finished. Answer of server was: "+rsp);
	        
		} finally {
			if(connection != null) {
				connection.disconnect();
			}
			
			if(fileInputStream != null) {
				fileInputStream.close();
			}
		}
		
		return rsp;
	}
	
	
	public static String sendMessage(String server, String msg, String ts, String pid) throws IOException{
		String rsp = "";
		
		HttpURLConnection connection = null;
		FileInputStream fileInputStream = null;
		try {
			
			Log.i(TAG, FileUploadUtil.class.getName()
					+ " Try to send cancel.");						
			
			URL connectURL = new URL("http://" + server);
			
			//get new http connection -> cast according to http://developer.android.com/reference/java/net/HttpURLConnection.html
			connection = (HttpURLConnection) connectURL.openConnection();
			
			//setup before connection becomes alive
			connection.setDoInput(true); 
			connection.setDoOutput(true); 
			connection.setUseCaches(false);
			connection.setRequestProperty("ACCEPT_CHARSET", "utf-8");
			connection.setRequestMethod("POST");
			connection.setRequestProperty("Connection", "Keep-Alive");
			connection.setRequestProperty("Content-Type","multipart/form-data;boundary=" + boundary);
			
			DataOutputStream dataOutputStream = new DataOutputStream(connection.getOutputStream());
			
			dataOutputStream.writeBytes("--" + boundary + lineEnding);
			dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"tsexperimentstart\"" + lineEnding);
			dataOutputStream.writeBytes(lineEnding);
			dataOutputStream.writeBytes(ts + lineEnding);
			dataOutputStream.writeBytes("--" + boundary + lineEnding);
			dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"participantid\"" + lineEnding);
			dataOutputStream.writeBytes(lineEnding);
			dataOutputStream.writeBytes(pid + lineEnding);
			dataOutputStream.writeBytes("--" + boundary + lineEnding);			
			dataOutputStream.writeBytes("Content-Disposition: form-data; name=\"message\"" + lineEnding);
			dataOutputStream.writeBytes(lineEnding);
			dataOutputStream.writeBytes(msg + lineEnding);
			dataOutputStream.writeBytes("--" + boundary + lineEnding);			
			
			dataOutputStream.flush();
			
			BufferedReader bufferedReader  = new BufferedReader(new InputStreamReader(connection.getInputStream()));
	        StringBuilder stringBuilder = new StringBuilder();
	        String line;
	        while((line = bufferedReader.readLine()) != null) {
	        	stringBuilder.append(line + '\n');
	        }
	        
	        rsp = stringBuilder.toString();
	        
		} finally {
			if(connection != null) {
				connection.disconnect();
			}
			
			if(fileInputStream != null) {
				fileInputStream.close();
			}
		}
		
		return rsp;
	}
	
	
	
	/**
	 * Depends on insights from
	 * http://www.sergiy.ca/how-to-make-java-md5-and-sha-1-hashes-compatible-with-php-or-mysql/
	 * 
	 * @param theTextFile
	 * @return
	 */
	public static final String md5HashTextFile(File theTextFile){
		String md5Hash = null;
		String theTextFileAsString = null;
		FileInputStream input = null;
		BufferedReader bReader = null;

		
		try{
			input = new FileInputStream(theTextFile.getPath());
		
			if(input!=null){
				bReader = new BufferedReader(new InputStreamReader (input),FileUploadUtil.BUFFERSIZE);
				String sline = null;
				final StringBuilder sBuilder = new StringBuilder(FileUploadUtil.BUFFERSIZE);
				while((sline=bReader.readLine())!=null){
					sBuilder.append(sline);	
				}
				theTextFileAsString = sBuilder.toString();
			}
							
			if(theTextFileAsString != null) {
		        MessageDigest md = MessageDigest.getInstance(algo); //or "SHA-1"
		        md.update(theTextFileAsString.getBytes());
		        BigInteger hash = new BigInteger(1, md.digest());
		        md5Hash = hash.toString(16);
		        while(md5Hash.length() < 32) { //40 for SHA-1
		        	md5Hash = "0" + md5Hash;
		        }
		    }
			
		}
		catch(IOException io){
			Log.e(TAG, FileUploadUtil.class.getName()
					+ ": Cannot open file:  "
					+ theTextFile.getAbsolutePath());

		}
		catch(NoSuchAlgorithmException nsae){
			Log.e(TAG, FileUploadUtil.class.getName()
					+ "Algorithm "+algo+"does not exist in java.security.MessageDigest");
		}
		
		finally{
		if(input != null) {
			try{
				input.close();
			}catch(IOException io){
				Log.e(TAG, FileUploadUtil.class.getName()
						+ ": Cannot close inputstream:   "
						+ theTextFile.getAbsolutePath());
			}
		}
		if(bReader != null){
			try{
			bReader.close();
			}catch(IOException io){
				Log.e(TAG, FileUploadUtil.class.getName()
						+ ": Cannot close bufferedReader:   "
						+ theTextFile.getAbsolutePath());
			}
		}
	}
		
		
		
		return md5Hash;
	
	}
	
}
